# -*- coding: utf-8 -*-
# created on 2016/05/17

from __future__ import division
from sympy import S
from mathsolver.functions.base import BaseFunction, BaseNumber, BaseEq, BaseVariable, new_latex
from mathsolver.functions.hanshu.dingyiyu import QiuDingYiYu
from mathsolver.functions.hanshu.helper import check_func
from mathsolver.functions.root.jiefangchen import JieFangChen


class HanShuLinDianZuoBiao(BaseFunction):
    """求函数零点坐标"""

    def solver(self, *args):
        func = check_func(args[0])
        expression = func.expression
        stepsolver = JieFangChen().solver(BaseEq([expression, S.Zero]))
        self.steps += stepsolver.steps
        self.label.update(stepsolver.label)
        self.output.extend(stepsolver.output)
        self.label.add("求函数零点坐标")
        return self


class XaJiaoDian(BaseFunction):
    """函数与x=a的交点个数"""

    def solver(self, *args):
        eq1, eq2 = args
        a = eq2.sympify()[1]

        dingyiyu = QiuDingYiYu().solver(eq1)
        self.steps.append(["", "函数 %s 的定义域为 %s" % (eq1.printing(), new_latex(dingyiyu))])

        # f(x) 在 x = a 有定义 => 1 个交点
        if a in dingyiyu:
            res = 1
            self.steps.append(["", "%s 在 %s 有定义，交点个数为 1" % (eq1.printing(), eq2.printing())])
        # f(x) 在 x = a 无定义 => 0 个交点
        else:
            res = 0
            self.steps.append(["", "%s 在 %s 无定义，交点个数为 1" % (eq1.printing(), eq2.printing())])

        self.label.add("函数与x=a的交点个数")
        self.output.append(BaseNumber(res))

        return self


class LingDianQuJian(BaseFunction):
    """hs101.判断零点/方程根/函数交点所在区间"""

    def solver(self, *args):
        # 处理输入，如果3个输入，则求函数交点
        if len(args) == 3:
            func1, func2, qujian = check_func(args[0]), check_func(args[1]), args[2].interval
            var = func1.var
            expr = func1.expression - func2.expression
            self.steps.append(["", "2个函数的交点转换为函数 f(x) = %s 零点所在区间" % expr])
        # 否则，求方程根
        else:
            func = check_func(args[0])
            qujian = args[1].interval
            expr, var = func.expression, func.var

        left, right, left_open, right_open = qujian.args
        f_left, f_right = expr.subs(var, left), expr.subs(var, right)

        res = False
        if f_left * f_right < 0:
            res = True
            self.steps.append(
                ["", " f(%s) * f(%s) < 0" % (left, right)])
        elif not left_open:
            if f_left == 0:
                res = True
                self.steps.append(["f(%s) = 0" % left])
        elif not right_open:
            if f_right == 0:
                res = True
                self.steps.append(["f(%s) = 0" % right])
        if res:
            self.steps.append(["", "所以函数 %s 在区间 %s 上存在零点" % (new_latex(expr), qujian)])
        else:
            self.steps.append(["", "函数 %s 在区间 %s 上不存在零点" % (new_latex(expr), qujian)])

        self.output.append(BaseVariable(res))
        self.label.add("判断零点/方程根/函数交点所在区间")
        return self


if __name__ == '__main__':
    pass
    # print "============== 求函数零点 ==========================="
    # print hanshu_lindian_zuobiao().solver(BaseEq(["y", "x**2-9"])).output[0].printing()
    # print hanshu_lindian_zuobiao().solver(BaseEq(["y", "1 - log(x, 2)"])).output[0].printing()
    #
    # print "============== 与 x=a 交点个数 ==========================="
    # for s1, s2 in xa_jiaodian().solver(BaseEq(['y', 'x**2']), BaseEq(['x', '2'])).steps: print s1, s2
    # for s1, s2 in xa_jiaodian().solver(BaseEq(['y', 'log(x, 2)']), BaseEq(['x', '-2'])).steps: print s1, s2
    #
    # print "============== 判断零点/方程根/函数交点所在区间 ==========================="
    # for s1, s2 in lingdian_qujian().solver(BaseEq(['y', 'x**5+x-3']),
    #                                        BaseInter(["[", "1", "2", ")"])).steps: print s1, s2
    #
    # for s1, s2 in lingdian_qujian().solver(BaseEq(['y', 'x**5+x-3']),
    #                                        BaseInter(["[", "0", "1", ")"])).steps: print s1, s2
    #
    # for s1, s2 in lingdian_qujian().solver(BaseEq(['y', 'x**3']), BaseEq(['y', '(1/2)**x']),
    #                                        BaseInter(["[", "0", "1", ")"])).steps: print s1, s2
